package com.cskaoyan.order.mq.delay;


import com.cskaoyan.order.constant.OrderConstants;
import com.cskaoyan.order.dal.entitys.Order;
import com.cskaoyan.order.dal.entitys.OrderItem;
import com.cskaoyan.order.dal.entitys.OrderList;
import com.cskaoyan.order.dal.entitys.Stock;
import com.cskaoyan.order.dal.persistence.OrderItemMapper;
import com.cskaoyan.order.dal.persistence.OrderMapper;
import com.cskaoyan.order.dal.persistence.StockMapper;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.PostConstruct;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;

/**
 * @author bai
 * @since 2022/08/02 23:29
 */
@Component
public class DelayOrderCancelConsumer {
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderItemMapper orderItemMapper;
    @Autowired
    StockMapper stockMapper;

    private DefaultMQPushConsumer consumer;
    @PostConstruct
    public void init(){
        consumer = new DefaultMQPushConsumer("delay_order_cancel_consumer");
        consumer.setNamesrvAddr("127.0.0.1:9876");
        consumer.setMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                // 订单超时自动取消的逻辑
                //1、从消息体中获取orderId
                try {
                    MessageExt message = msgs.get(0);
                    byte[] body = message.getBody();
                    String orderId = new String(body, 0, body.length, "utf-8");

                    // 2、根据orderId修改订单的状态
                    // 先进行订单状态的查询操作
                    Order order = orderMapper.selectByPrimaryKey(orderId);
                    // 如果是已支付或已取消，什么都不做
                    // 如果订单的状态还是初始化状态，执行订单的超时自动取消
                    if(order.getStatus() == OrderConstants.ORDER_STATUS_INIT){
                        // 调用支付服务，取消订单交易，返回成功与否的结果
                        // 当取消成功时：
                        //  将订单状态修改为取消
                        Order updateOrder = new Order();
                        updateOrder.setOrderId(orderId);
                        updateOrder.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
                        updateOrder.setUpdateTime(new Date(System.currentTimeMillis()));

                        int arrowLine = orderMapper.updateByPrimaryKeySelective(updateOrder);
                        if(arrowLine >= 1){
                            // 取消成功
                            //  根据orderId，查询出所有的订单商品条目，根据订单商品条目的购买数量
                            //      + stockCount  -lockCount
                            // 更改库存
                            Example example = new Example(OrderItem.class);
                            Example.Criteria criteria = example.createCriteria();
                            criteria.andEqualTo("orderId",orderId);

                            List<OrderItem> orderItems = orderItemMapper.selectByExample(example);

                            for (OrderItem orderItem : orderItems) {
                                Stock stock = new Stock();
                                // 给将orderItem中的属性赋值给stock
                                BeanUtils.copyProperties(orderItem,stock);
                                stockMapper.updateStock(stock);
                            }
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
        try {
            consumer.subscribe("delay_order_cancel","*");
            consumer.start();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
    }
}
